package helpers;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.TreeMap;
import java.util.concurrent.Future;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

import entities.Domain;
import entities.IpAddress;

public class CrawlerDomainHelper {
	
	private TreeMap<String, String> check = new TreeMap<String, String>();
	
	private URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
	
	private Future fWhoisIp = null;
	
	private Future fWhois = null;
	
	private IpAddress ipAddress = null;
	
	private Domain domain = null;
	
	private TreeMap<String, String> getCheck() {
        return check;
    }
	
	public IpAddress getIpAddress() {
		return this.ipAddress;
	}
	
	public IpAddress getIp(IpAddress ipa) {
		ipAddress = ipa;
		if (ipAddress != null) {
			loadUrlWhoisIp();
	        
			getWhoisIp();
		}
		
		return this.ipAddress;
	}
	
	public Domain getWhois(Domain d) {
		domain = d;
		if (domain != null && domain.getWhois().isEmpty()) {
			loadUrlWhois();
			
			getWhois();
		}
		
		return domain;
	}
	
	private void loadUrlWhoisIp() {
    	try {
            URL urlWhoisIp = new URL("http://www.statscrop.com/ip/?ip=" + ipAddress.getIp());
            fWhoisIp = fetcher.fetchAsync(urlWhoisIp);
            
        } catch (Exception e) {
            check.put("fWhoisIp", "Can't run fWhoisIp");
        }
    }
	
	private void loadUrlWhois() {
        try {
            URL urlWhois = new URL("http://www.whoisdata.us/whois/" + this.domain.getDomain());
            fWhois = fetcher.fetchAsync(urlWhois);
        } catch (Exception e) {
            check.put("fWhois", "Can't run fWhois");
        }
    }
	
	private void getWhoisIp() {
    	try {
			HTTPResponse response = (HTTPResponse) fWhoisIp.get();
			Document doc = Jsoup.parse(this.getContentCharset(response));
			Elements ipInfo = doc.select("#content .attributes ");
			
			String countryCode = ipInfo.select("dd:eq(1)").html();
			String countryCode3 = ipInfo.select("dd:eq(3)").html();
			String countryName = StringHelper.html2text(ipInfo.select("dd:eq(5)").html());
			String city = ipInfo.select("dd:eq(7)").html();
			String continentCode = ipInfo.select("dd:eq(9)").html();
			String latitude = ipInfo.select("dd:eq(11)").html();
			latitude = convertGeo(latitude);
			String longitude = ipInfo.select("dd:eq(13)").html();
			longitude = convertGeo(longitude);
			
			String whoisIp = doc.select("#innercontent2 > div").eq(2).html();
			
			ipAddress.setIp(ipAddress.getIp());
			ipAddress.setCountryCode(countryCode);
			ipAddress.setCountryCode3(countryCode3);
			ipAddress.setCountryName(countryName);
			ipAddress.setCity(city);
			ipAddress.setContinentCode(continentCode);
			ipAddress.setLatitude(latitude);
			ipAddress.setLongitude(longitude);
			ipAddress.setWhoisIp(whoisIp);
			
		} catch (Exception e) {
			ipAddress = null;
			check.put("whoisIp", "Can't get whois ip " + ipAddress.getIp());
		}
	}	
	
	private void getWhois() {
        try {
            HTTPResponse response = (HTTPResponse) fWhois.get();
            Document doc = Jsoup.parse(this.getContentCharset(response));
            String whois = doc.select("#content .whois").html();
            if (!whois.isEmpty()) {
            	whois = whois.replaceAll("[<]{1}(a)[^>]+[>]{1}", "").replaceAll("<\\/a>", "");
				//whois = whois.replaceAll("(src=\")", "src=\"http://www.whoismind.com");
            	this.domain.setWhois(whois);
            }
        } catch (Exception e) {
            check.put("fWhois", "Error when get value whois");
        }
    }
	
	/********************************************* LIBRARY FUNCTION *********************************************/
	private String getContentCharset(HTTPResponse response) {
        String charset = "UTF-8";
        String content = "";
        try {
			content = new String(response.getContent(),charset);
			Document doc = Jsoup.parse(content);
	        
	        int index = doc.select("meta").toString().toLowerCase().indexOf("charset=");
	        if (index != -1) {
	        	charset = doc.select("meta").toString().substring(index + 8).replaceAll("[^\\'\\\"0-9a-zA-Z\\-\\_]+[\\w\\W]+", "").replaceAll("[\\'\\\"]+", "");
	        }
	        content = new String(response.getContent(),charset);
	        
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
        
    	return content;
    }
	
	private static String convertGeo(String geo) {
		geo = geo.replace("&deg;", ".").replace("'", "").replace("\"", "");
		geo = geo.replaceAll("[^0-9.]", "");
		return geo;
	}
}
